﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Dynamic;
using System.Runtime.Serialization;

namespace StateManager
{
    [DataContract]
    /// <summary>
    /// 状态机实例
    /// </summary>
    public class SInfo
    {
        #region 配置文件相关

        [DataMember(EmitDefaultValue = true, Order = 0)]
        /// <summary>
        /// 实例名称,在配置文件中预定义，状态机中不允许重复
        /// </summary>
        public string Name = "";
        [DataMember(Order = 1)]
        /// <summary>
        /// 实例类型
        /// </summary>
        public string Type = "";
        bool auto = false;
        /// <summary>
        /// 是否自动，在配置文件中预定义，也可代码控制
        /// </summary>
        [DataMember(Order = 2)]
        public bool Auto
        {
            get { return auto; }
            set
            {
                if (auto != value) { auto = value; if (JObject != null) JObject["Auto"] = value; Updated(); }
            }
        }
        /// <summary>
        /// 实例描述,在配置文件中预定义
        /// </summary>
        [DataMember(Order = 3)]
        public string Tip = "";
        /// <summary>
        /// 父对象，用于对象列表的分级
        /// </summary>
        [DataMember(Order = 4)]
        public string Parent = "";
        /// <summary>
        /// 主配置文件中每个实例的json，便于二次开发补充配置
        /// </summary>
        public Newtonsoft.Json.Linq.JObject JObject = new Newtonsoft.Json.Linq.JObject();
        /// <summary>
        /// 每个实例名对应的标准配置
        /// </summary>
        public object Config;
        #endregion

        #region Engine状态

        ///// <summary>
        ///// SInfo中扩展的配置，需要在StateInit()中调用SetConfig<XXX>()，其中XXX为自定义配置类
        ///// </summary>
        //object _config;
        ///// <summary>
        ///// Json配置内容，转换为 _config 之后清空不再使用
        ///// </summary>
        //[DataMember]
        //internal string _ConfigString;
        //public T GetConfig<T>()
        //{
        //    if (_config == null)
        //    {
        //        _config = SManager.JsonToObject<T>(_ConfigString);
        //        _ConfigString = null;
        //    }
        //    return (T)_config;
        ////}
        //public void SaveConfigToFile()
        //{
        //    if (_config != null)
        //    {


        //    }
        //}

        /// <summary>
        /// 管理器
        /// </summary>
        public SManager Manager;
        public bool Initialized { get; internal set; } = false;
        public bool Working { get; internal set; } = false;
        public string LastState;
        string state = "";
        /// <summary>
        /// 当前状态
        /// </summary>
        public string State
        {
            get { return state; }
            set
            {
                if (state != value) { state = value; if (JObject != null) JObject["State"] = value; Updated(); }
            }
        }
        string engineStep;
        /// <summary>
        /// 状态机内部处理步骤
        /// </summary>
        public string EngineStep
        {
            get { return engineStep; }
            set
            {
                if (engineStep != value) { engineStep = value; Updated(); }
            }
        }
        string status = "";
        /// <summary>
        /// 当前状态描述
        /// </summary>
        public string Status
        {
            get { return status; }
            set
            {
                if (status != value) { status = value; Updated(); }
            }
        }
        /// <summary>
        /// 下一状态
        /// </summary>
        public string NextState = "";
        string nextStatus = "";
        /// <summary>
        /// 下一状态描述
        /// </summary>
        public string NextStatus
        {
            get { return nextStatus; }
            set
            {
                if (nextStatus != value) { nextStatus = value; Updated(); }
            }
        }


        /// <summary>
        /// 单次强制状态，优先于StateHandle中的设置，用于复位
        /// </summary>
        internal string TheResetState = null;
        /// <summary>
        /// 单次、立即强制状态
        /// </summary>
        /// <param name="State"></param>
        public void ResetState(string State = "")//非脚本强制切换,可用SetNextState
        {
            TheResetState = State;
            Status = "";
            NextCheckTime = DateTime.Now;
        }
        public DateTime NextCheckTime;
        public object Object;
        //2020年3月8日增加，加快访问其他Object效率
        /// <summary>
        /// 配置文件中Link内属性的动态关联，用于快速访问关联资源，注意使用强类型模式保存主配置文件时会丢失此配置
        /// </summary>
        public ExpandoObject Link = new ExpandoObject();
        public ExpandoObject _userData = new ExpandoObject();
        /// <summary>
        /// 用户自定义数据的获取
        /// </summary>
        /// <param name="Key"></param>
        /// <returns></returns>
        public object GetUserData(string Key)
        {
            //return userdata[Key];
            IDictionary<string, object> dic = _userData;
            if (dic != null && dic.ContainsKey(Key))
                return dic[Key];
            return null;
        }
        /// <summary>
        /// 用户自定义数据的添加、修改
        /// </summary>
        /// <param name="Key"></param>
        /// <param name="Data"></param>
        public void SetUserData(string Key, dynamic Value)
        {
            IDictionary<string, object> dic = _userData;
            dic[Key] = Value;
        }
        /// <summary>
        /// 实例的用户更新事件，绑定所有相关界面更新,第1个参数为相应的SObject
        /// </summary>
        public Action OnUpdated;
        public void Updated()
        {
            if (OnUpdated != null)
                OnUpdated.Invoke();
        }

        /// <summary>
        /// 设置下一状态
        /// </summary>
        /// <param name="State">状态名称（需有相应状态的处理代码）</param>
        /// <param name="milliSecsLater">延时执行（单位：毫秒）</param>
        /// <param name="Status">状态描述</param>
        public void SetNextState(string State, int milliSecsLater = 0, string NextStatus = null) //主线程
        {
            NextState = State;
            NextCheckTime = DateTime.Now.AddMilliseconds(milliSecsLater);
            if (NextStatus != null)
            {
                this.NextStatus = NextStatus;
            }
        }
        /// <summary>
        /// 设置为重复当前状态
        /// </summary>
        /// <param name="milliSecsLater">延时执行（单位：毫秒）</param>
        /// <param name="Status">状态描述</param>
        public void RepeatState(int milliSecsLater, string NextStatus = null)
        {
            SetNextState(State, milliSecsLater, NextStatus);
        }

        public Hashtable IntervalTimes = new Hashtable();

        /// <summary>
        /// 信号最短执行周期定时器
        /// </summary>
        /// <param name="TimerName">定时器名称（自动添加、修改）</param>
        /// <param name="Interval">毫秒数</param>
        /// <returns></returns>
        public bool OnTime(string TimerName, int Interval)
        {
            object f = IntervalTimes[TimerName];
            if (f == null)
            {
                IntervalTimes.Add(TimerName, DateTime.Now);
                return true;
            }
            else
            {
                DateTime t = (DateTime)f;
                if ((DateTime.Now - t).TotalMilliseconds > Interval)
                {
                    t = DateTime.Now;
                    IntervalTimes[TimerName] = t;
                    return true;
                }
                return false;
            }

        }
        public void Log(string Text, bool ManualMode = false)
        {
            Manager.Log(Name, Text, ManualMode);
        }

        #endregion
    }
}